import os
import time
from concurrent.futures import ThreadPoolExecutor

import cv2 as cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont


def filter_pictures(filename):
    return list(filter(lambda x: x.endswith('.jpg'), filename))


def video2files(video_name, size=None):
    imgs = []
    cap = cv2.VideoCapture(video_name)
    while cap.isOpened():
        ret, frame = cap.read()
        if ret:
            print(f"\rReading video.... {1 + len(imgs)}...", end='')
            if size is None:
                pass
            else:
                frame = cv2.resize(frame, size, interpolation=cv2.INTER_AREA)
            # imgs.append(Image.fromarray(frame))
            imgs.append(frame)
        else:
            break
    cap.release()
    return imgs


def get_char(r, g, b, alpha=256):
    pixels = r" .,-'`:1*bdfhjlnprtvxz>)/}]24680BDFHJLNPRTVX%@$"
    if alpha == 0:
        return ''
    gray = int(0.299 * r + 0.587 * g + 0.114 * b)
    unit = (256.0 + 1) / len(pixels)
    return pixels[int(gray / unit)]


def raw2file(imgpath, index, save_dir):

    im = Image.open(imgpath).convert('RGB')
    raw_width, raw_height = im.size
    width, height = int(raw_width / 6), int(raw_height / 14)
    im = im.resize((width, height), Image.NEAREST)

    txt = ''
    color = []
    for i in range(height):
        for j in range(width):
            pixel = im.getpixel((j, i))
            color.append((pixel[0], pixel[1], pixel[2]))
            if len(pixel) == 4:
                txt += get_char(pixel[0], pixel[1], pixel[2], pixel[3])
            else:
                txt += get_char(pixel[0], pixel[1], pixel[2])
        txt += '\n'
        color.append((175, 175, 175))

    im_txt = Image.new("RGB", (raw_width, raw_height), (175, 175, 175))
    dr = ImageDraw.Draw(im_txt)
    font = ImageFont.load_default().font
    x, y = 0, 0
    font_w, font_h = font.getsize(txt[1])
    font_h *= 1.37  # 调整字体大小
    for i in range(len(txt)):
        if (txt[i] == '\n'):
            x += font_h
            y = -font_w
        dr.text((y, x), txt[i], fill=color[i])
        y += font_w
    im_txt.save(f'{save_dir}/{index}.jpg')
    print(f"{save_dir}/{index}.jpg save ok")


def showfiles(file_dir):
    cv2.namedWindow('video')
    cv2.waitKey(0)
    files = filter_pictures(os.listdir(file_dir))
    for i in range(len(files)):
        img = cv2.imread(f'{file_dir}/{i}.jpg')
        cv2.imshow('video', img)
        if cv2.waitKey(20) & 0xff == 27:
            break


def imgWrite(img, index):
    cv2.imwrite(f'./imgs/raw/{index}.jpg', img)
    print(f"{index}.jpg write ok")


def getRawImage(imgs):
    with ThreadPoolExecutor(40) as executor:
        for index, img in enumerate(imgs):
            executor.submit(imgWrite, img, index)


def rawlist2files(imgdir, savedirname):
    files = filter_pictures(os.listdir(imgdir))
    # raw2file(f'{imgdir}/{files[44]}', 44, savedirname)
    with ThreadPoolExecutor(60) as executor:
        for index in range(len(files)):
            executor.submit(raw2file, f'{imgdir}/{index}.jpg', index,
                            savedirname)


if __name__ == "__main__":
    '''
    imgs = video2files('./vedio/juren.flv')
    getRawImage(imgs)
    rawlist2files('./imgs/raw', './imgs/chars')
    '''
    showfiles('./imgs/chars')
